# hierarchical clustering

from sklearn.cluster import AgglomerativeClustering
import numpy as np
import gensim
import jieba


def hc(texts, reads, urls, nlp_service, n_clusters=100):

    vectors = nlp_service.get_word_vectors(texts)
    if len(texts) > n_clusters:
        vectors = np.array(vectors)
        hc_model = AgglomerativeClustering(n_clusters=n_clusters, linkage="ward")
        hc_model.fit(vectors)
        labels = hc_model.labels_
    else:
        labels = range(0, len(texts))

    res = {}
    tmp = []

    for d, l, r, url in zip(texts, labels, reads, urls):
        res[str(l)] = res.get(str(l), []) + [(d, r, url)]

    for k, v in res.items():
        tmp.append(([{'title': t, 'read_num': r, 'url': url} for t, r, url in
                     sorted(v, key=lambda x: x[1], reverse=True)], sum([m[1] for m in v])))

    res = [{'title_read': k, 'sum_read': v} for k, v in sorted(tmp, key=lambda x: x[1], reverse=True)]
    return res


def hc2(texts, reads, urls, summaries, n_clusters=100):
    titles = [jieba.lcut(t) for t in texts]
    sentences = [jieba.lcut(t) for t in summaries] + titles
    word2vec_model = gensim.models.Word2Vec(sentences, window=4, min_count=1, size=100, workers=2)
    out = []
    for i, d in enumerate(sentences):
        vectors = []
        for k in d:
            try:
                vec = word2vec_model[k]
                vectors.append(vec)
            except Exception as e:
                print(str(e))

        if len(vectors) > 0:
            v = np.array(vectors).sum(axis=0) / len(vectors)
            out.append(v.tolist())

    if len(texts) > n_clusters:
        vectors = np.array(out)
        hc_model = AgglomerativeClustering(n_clusters=n_clusters, linkage="ward")
        hc_model.fit(vectors)
        labels = hc_model.labels_
    else:
        labels = range(0, len(texts))

    res = {}
    tmp = []

    for d, l, r, url in zip(texts, labels, reads, urls):
        res[str(l)] = res.get(str(l), []) + [(d, r, url)]

    for k, v in res.items():
        tmp.append(([{'title': t, 'read_num': r, 'url': url} for t, r, url in
                     sorted(v, key=lambda x: x[1], reverse=True)], sum([m[1] for m in v])))

    res = [{'title_read': k, 'sum_read': v} for k, v in sorted(tmp, key=lambda x: x[1], reverse=True)]
    return res

